/*
@Time : 2020/12/29 11:24 上午
@Author : chenle
@File : event
@Software: GoLand
*/
package lego

import "runtime/debug"

type Event func(*Context)

type Events []Event

func (e Events) Handle(c *Context) {
	defer func() {
		if e := recover(); e != nil {
			SysErrorf("recover from the handle chain (index : %d) , err: %s\nstack: %s", c.index, e, debug.Stack())
		}
	}()
	for _, evt := range e {
		c.mu.Lock()
		flag := c.IsOver
		index := c.index
		c.mu.Unlock()
		if !flag && index >= 0 {
			evt(c)
			c.index++
		} else {
			return
		}
	}
}

func (e Events) AfterHandle(c *Context) {
	defer func() {
		if e := recover(); e != nil {
			SysErrorf("recover from the handle chain of after filters (index : %d) , err: %s\nstack: %s", c.index, e, debug.Stack())
		}
	}()

	c.IsOver = false
	c.index = 0

	for _, evt := range e {
		c.mu.Lock()
		flag := c.IsOver
		index := c.index
		c.mu.Unlock()
		if !flag && index >= 0 {
			evt(c)
			c.index++
		} else {
			return
		}
	}
}

func (e Events) BeforeHandle(c *Context) {
	defer func() {
		if e := recover(); e != nil {
			SysErrorf("recover from the handle chain of before filters (index : %d) , err: %s\nstack: %s", c.index, e, debug.Stack())
		}
	}()

	for _, evt := range e {
		c.mu.Lock()
		flag := c.IsOver
		index := c.index
		c.mu.Unlock()
		if !flag && index >= 0 {
			evt(c)
			c.index++
		} else {
			c.index = 0
			return
		}
	}
	c.index = 0
}
